package com.sunjs.filter;

import com.alibaba.fastjson.JSON;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

/**
 * Created by yangbin on 2017/11/15
 */
@Component
public class AccessLogFilter extends ZuulFilter {

	private static final Logger logger = LoggerFactory.getLogger(AccessLogFilter.class);

	/**
	 * to classify a filter by type. Standard types in Zuul are "pre" for pre-routing filtering,
	 * "route" for routing to an origin, "post" for post-routing filters, "error" for error handling.
	 * We also support a "static" type for static responses see  StaticResponseFilter.
	 * Any filterType made be created or added and run by calling FilterProcessor.runFilters(type)
	 *
	 * @return A String representing that type
	 */
	@Override
	public String filterType() {
		return FilterConstants.POST_TYPE;
	}

	/**
	 * filterOrder() must also be defined for a filter. Filters may have the same  filterOrder if precedence is not
	 * important for a filter. filterOrders do not need to be sequential.
	 *
	 * @return the int order of a filter
	 */
	@Override
	public int filterOrder() {
		return 0;
	}

	/**
	 * a "true" return from this method means that the run() method should be invoked
	 *
	 * @return true if the run() method should be invoked. false will not invoke the run() method
	 */
	@Override
	public boolean shouldFilter() {
		return true;
	}

	/**
	 * if shouldFilter() is true, this method will be invoked. this method is the core method of a ZuulFilter
	 *
	 * @return Some arbitrary artifact may be returned. Current implementation ignores it.
	 */
	@Override
	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		String uri = ctx.getRequest().getRequestURI();
		try {
			String queryParam = JSON.toJSONString(ctx.getRequest().getParameterMap());
//		logger.info("[zuul request info] url: " + uri + "; param: " + queryParam);

			InputStream is = ctx.getResponseDataStream();
			String response = IOUtils.toString(is, Charset.defaultCharset());
			logger.info("[zuul request info] url: " + uri + "; param: " + queryParam + "; [zuul response info]: " + response);
			ctx.setResponseDataStream(IOUtils.toInputStream(response, Charset.defaultCharset()));
		} catch (IOException e) {
			logger.error("记录访问日志异常：", e);
			// TODO 需测试异常后，返回数据是否有丢失
		}

		return null;
	}
}
